// <copyright file="FteOwnerRequirementUI.cs" company="Microsoft IT">
// Copyright © 2009 All Right Reserved
// </copyright>
// <author>Dmitry Kazantsev</author>
// <date>2010-01-22</date>
// <summary>Contains FteOwnerRequirementUI class</summary>

namespace Microsoft.Msit.ActivityLibrary
{
    using System;
    using System.Diagnostics.CodeAnalysis;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Workflow.ComponentModel;
    using Microsoft.IdentityManagement.WebUI.Controls;
    using Microsoft.ResourceManagement.Workflow.Activities;

    /// <summary>
    /// Represents User Interface class for the custom activity
    /// </summary>
    [SuppressMessage("Microsoft.Performance", "CA1812:AvoidUninstantiatedInternalClasses", Justification = "Used by FIM's 'Activity Information Configuration'")]
    public class FteOwnerRequirementUI : ActivitySettingsPart
    {
        /// <summary>
        /// The name of the custom UI control used to display object type value
        /// </summary>
        private const string ControlNameObjectType = @"controlObjectTypeName";

        /// <summary>
        /// Value representing default object type name
        /// </summary>
        private const string DefaultObjectTypeName = @"Group;";

        /// <summary>
        /// Variable containing mode of the activity
        /// </summary>
        private bool edit;

        /// <summary>
        /// Object to store table 
        /// </summary>
        private Table table;

        /// <summary>
        /// Initializes a new instance of the FteOwnerRequirementUI class
        /// </summary>
        public FteOwnerRequirementUI()
        {
            this.table = new Table();
            this.edit = true;
        }

        /// <summary>
        /// Gets the title of the activity
        /// </summary>
        public override string Title
        {
            get
            {
                return Constants.ActivityName;
            }
        }

        /// <summary>
        /// Generates a workflow activity and sets the attributes for that activity
        /// </summary>
        /// <param name="workflow">The workflow instance</param>
        /// <returns>Activity object</returns>
        public override Activity GenerateActivityOnWorkflow(SequentialWorkflow workflow)
        {
            FteOwnerRequirement activity = new FteOwnerRequirement();
            activity.ObjectTypeName = this.GetControlValue(ControlNameObjectType);
            return activity;
        }

        /// <summary>
        /// Overriding interface method
        /// </summary>
        /// <param name="activity">The activity object</param>
        public override void LoadActivitySettings(Activity activity)
        {
            FteOwnerRequirement activityTwo = activity as FteOwnerRequirement;

            if (null != activityTwo)
            {
                this.SetControlValue(ControlNameObjectType, activityTwo.ObjectTypeName);
            }
        }

        /// <summary>
        /// Override of the PersistSettings method
        /// </summary>
        /// <returns>ActivitySettingsPartData class</returns>
        public override ActivitySettingsPartData PersistSettings()
        {
            ActivitySettingsPartData data = new ActivitySettingsPartData();
            data[Constants.PropertyNameObjectType] = this.GetControlValue(ControlNameObjectType);
            return data;
        }

        /// <summary>
        /// Override of RestoreSettings method
        /// </summary>
        /// <param name="data">ActivitySettingsPartData in question</param>
        public override void RestoreSettings(ActivitySettingsPartData data)
        {
            if (null != data)
            {
                this.SetControlValue(ControlNameObjectType, data[Constants.PropertyNameObjectType] as string);
            }
        }

        /// <summary>
        /// Override of SwitchMode method
        /// </summary>
        /// <param name="mode">ActivitySettingsPartMode in question</param>
        public override void SwitchMode(ActivitySettingsPartMode mode)
        {
            bool flag = mode != ActivitySettingsPartMode.Edit;
            this.SetControlAccess(ControlNameObjectType, flag);
        }

        /// <summary>
        /// Override of ValidateInputs
        /// </summary>
        /// <returns>'true' whenever validation is successful or 'false' whenever validation is unsuccessful</returns>
        public override bool ValidateInputs()
        {
            return true;
        }

        /// <summary>
        /// Overrides CreateChildControls method
        /// </summary>
        protected override void CreateChildControls()
        {
            this.InitializeControls();
            base.CreateChildControls();
        }

        /// <summary>
        /// Adds a TableRow
        /// </summary>
        /// <param name="description">Description of the control</param>
        /// <returns>Well-formed TableRow object</returns>
        private static TableRow AddTableRow(Control description)
        {
            TableRow row = new TableRow();

            TableCell descriptionCell = CreateCell(description, 100.0);
            row.Cells.Add(descriptionCell);

            return row;
        }

        /// <summary>
        /// Adds pre-formatted Row to the table
        /// </summary>
        /// <param name="description">Description to be displayed</param>
        /// <param name="payload">Payload (Control or Text)</param>
        /// <returns>Well-formed TableRow object</returns>
        private static TableRow AddTableRow(Control description, Control payload)
        {
            TableRow row = new TableRow();

            TableCell descriptionCell = CreateCell(description, 70.0);
            row.Cells.Add(descriptionCell);

            TableCell controlCell = CreateCell(payload, 30.0);
            row.Cells.Add(controlCell);

            return row;
        }

        /// <summary>
        /// Creates TableCell
        /// </summary>
        /// <param name="control">Web Control</param>
        /// <param name="percentageWidth">Percentage width of the cell</param>
        /// <returns>Well-formed cell</returns>
        private static TableCell CreateCell(Control control, double percentageWidth)
        {
            TableCell cell = new TableCell();
            cell.Controls.Add(control);
            cell.Width = Unit.Percentage(percentageWidth);
            return cell;
        }

        /// <summary>
        /// Creates a TextBox control
        /// </summary>
        /// <param name="controlID">Control's ID</param>
        /// <param name="value">Control's Value</param>
        /// <param name="length">Control's length</param>
        /// <param name="mode">Mode type of the control</param>
        /// <param name="lines">Number of lines</param>
        /// <returns>Well-formed web-control</returns>
        private static TextBox CreateControl(string controlID, string value, int length, TextBoxMode mode, int? lines)
        {
            TextBox box = new TextBox();
            box.ID = controlID;
            box.Text = value;
            box.MaxLength = length;
            box.TextMode = mode;
            box.Width = Unit.Percentage(100.0);
            if (box.TextMode == TextBoxMode.MultiLine)
            {
                if (lines.HasValue)
                {
                    box.Rows = lines.Value;
                }
                else
                {
                    box.Rows = Math.Abs(Math.Min(6, (length + 60) / 60));
                }
            }

            return box;
        }

        /// <summary>
        /// Generates Web-Control
        /// </summary>
        /// <param name="controlID">Control's ID</param>
        /// <param name="value">Control's Value</param>
        /// <param name="controlType">Type of the Web-Control</param>
        /// <returns>Well-Formed Web-Control</returns>
        private Control CreateControl(string controlID, string value, Type controlType)
        {
            switch (controlType.Name.ToUpperInvariant())
            {
                case "TEXTBOX":
                    {
                        TextBox box = new TextBox();
                        box.CssClass = base.TextBoxCssClass;
                        box.ID = controlID;
                        box.Text = value;
                        box.Width = Unit.Percentage(100.0);
                        return box;
                    }

                case "LABEL":
                    {
                        Label label = new Label();
                        label.CssClass = base.LabelCssClass;
                        label.ID = controlID;
                        label.Text = value;
                        return label;
                    }

                default:
                    {
                        throw new System.DataMisalignedException("Cannot process control with type of " + controlType.Name);
                    }
            }
        }

        /// <summary>
        /// Gets string representing UI control
        /// </summary>
        /// <param name="controlID">Unique ID of the control</param>
        /// <returns>Content of the UI control</returns>
        private string GetControlValue(string controlID)
        {
            Control control = (Control)this.FindControl(controlID);
            if (null == control)
            {
                return string.Empty;
            }

            Type currentControlType = control.GetType();

            if (typeof(TextBox) == currentControlType)
            {
                TextBox box = (TextBox)control;
                return box.Text;
            }

            if (typeof(Label) == currentControlType)
            {
                Label label = (Label)control;
                return label.Text;
            }

            return string.Empty;
        }

        /// <summary>
        /// Initializes controls for this UI
        /// </summary>
        private void InitializeControls()
        {
            this.table.Width = Unit.Percentage(100.0);
            this.table.BorderWidth = 0;
            this.table.CellPadding = 1;

            Label activityDescription = (Label)CreateControl("descriptionLabel", "Ensures that every group has an FTE (co)owner", typeof(Label));
            this.table.Rows.Add(AddTableRow(activityDescription));

            if (this.edit)
            {
                {
                    Label description = (Label)CreateControl("objectTypeDescription", "Name of the object type:", typeof(Label));
                    TextBox control = CreateControl(ControlNameObjectType, DefaultObjectTypeName, int.MaxValue, TextBoxMode.SingleLine, null);
                    this.table.Rows.Add(AddTableRow(description, control));
                }
            }
            else
            {
                {
                    Label description = (Label)CreateControl("objectTypeDescription", "Name of the object type:", typeof(Label));
                    Label control = (Label)CreateControl(ControlNameObjectType, DefaultObjectTypeName, typeof(Label));
                    this.table.Rows.Add(AddTableRow(description, control));
                }
            }

            this.Controls.Add(this.table);
        }

        /// <summary>
        /// Sets Access control
        /// </summary>
        /// <param name="controlID">Control's unique ID</param>
        /// <param name="readOnly">Determines whether control should be rendered as read-only or not</param>
        private void SetControlAccess(string controlID, bool readOnly)
        {
            if (this.edit)
            {
                Control control = (Control)FindControl(controlID);

                if (control.GetType() == typeof(TextBox) && control != null)
                {
                    TextBox box = (TextBox)control;
                    box.ReadOnly = readOnly;
                }
            }
        }

        /// <summary>
        /// Sets control's content
        /// </summary>
        /// <param name="controlID">Unique Id of the control</param>
        /// <param name="value">Value to be set as a control's content</param>
        private void SetControlValue(string controlID, string value)
        {
            Control control = (Control)this.FindControl(controlID);

            if (null == control)
            {
                return;
            }

            Type currentControlType = control.GetType();

            if (typeof(TextBox) == currentControlType)
            {
                TextBox box = (TextBox)control;
                box.Text = value;
            }

            if (typeof(Label) == currentControlType)
            {
                Label label = (Label)control;
                label.Text = value;
            }
        }
    }
}
